package org.text2diagram.ddl.render;

import java.io.File;
import java.io.FileWriter;

import org.text2diagram.ddl.converter.DiagramDescription;
import org.text2diagram.ddl.converter.PlainTextConverter;
import org.text2diagram.ddl.converter.dot.DDLToDotConverter;
import org.text2diagram.ddl.converter.dot.ImageFormat;
import org.text2diagram.ddl.util.ScriptExecutor;

/**
 * Converts DDL into target diagram image using DDLToDotConverter
 * Result of conversion into DOT is stored as separate file for debug/investigation purposes
 * Output image format can be choosen between PNG and SVG

 * @author Svyatoslav Kryukov
 *
 */
public class DiagramRenderer {

	private String outputDirectory;
	private String diagramName;
	private ImageFormat outputFormat;
	//TODO: UGLY HACK!
	private String graphvizBinDirectory = "C:\\Program Files\\Graphviz2.22\\bin\\";
	
	public void render(String diagramName, ImageFormat outputFormat, String outputDirectory, String diagramDescription) throws Exception {
		DiagramDescription ddl = PlainTextConverter.convertDescription(diagramDescription);
		this.setDiagramName(diagramName);
		this.setOutputDirectory(outputDirectory);
		this.setOutputFormat(outputFormat);
		render(ddl);
	}

	private void render(DiagramDescription ddl) throws Exception {
		
		//1) convert DDL into DOT
		DDLToDotConverter ddlToDotConverter = new DDLToDotConverter();
		String dotOutput = ddlToDotConverter.convert(ddl, diagramName);
		
		//2) create/cleanup output directory
		File outputDir = new File(outputDirectory);
		if (outputDir.exists()) {
			outputDir.delete();
		}
		outputDir.mkdir();
		
		//3) write DOT result into file
		String dotFilePath = outputDirectory + "\\" + getDiagramName() + "." + "dot";
		File dotFile = new File(dotFilePath);
		FileWriter fileWriter = new FileWriter(dotFile);
		fileWriter.write(dotOutput);
		fileWriter.flush();
		fileWriter.close();
		
		//4) convert dot file into image by running GraphViz executable on the .dot and redirecting stdout to target file
		String imageFilename = diagramName + "." + outputFormat.name().toLowerCase();
		ScriptExecutor extDiagramBuilder = new ScriptExecutor("cmd", "/c", 
																graphvizBinDirectory  + "dot.exe", 
																diagramName + ".dot", 
																"-T" + outputFormat.name().toLowerCase(), 
																">", 
																imageFilename);
		extDiagramBuilder.setWorkingDir(outputDirectory);
		extDiagramBuilder.setMaxLines(20);
		extDiagramBuilder.execute();
		//4) all done, just check GV execution output
		System.out.println("Result code: " + extDiagramBuilder.getResultCode());
		System.out.println("Script output: \n" + extDiagramBuilder.getOutputTail());
		
	}	
	
	public void setOutputDirectory(String outputDirectory) {
		this.outputDirectory = outputDirectory;
	}

	public String getOutputDirectory() {
		return outputDirectory;
	}

	public void setDiagramName(String diagramName) {
		this.diagramName = diagramName;
	}

	public String getDiagramName() {
		return diagramName;
	}

	public void setOutputFormat(ImageFormat outputFormat) {
		this.outputFormat = outputFormat;
	}

	public ImageFormat getOutputFormat() {
		return outputFormat;
	}


	public void setGraphvizBinDirectory(String graphvizBinDirectory) {
		this.graphvizBinDirectory = graphvizBinDirectory;
	}


	public String getGraphvizBinDirectory() {
		return graphvizBinDirectory;
	}
	
}
